﻿namespace MicroCloud.Authorization
{
    #region "数据权限模块基类"
    /// <summary>
    /// 数据权限模块基类
    /// </summary>
    /// <typeparam name="TDataAuthorizationManager">数据权限管理器</typeparam>
    /// <typeparam name="TDataAuthCache">数据权限缓存</typeparam>
    /// <typeparam name="TEntityInfo">数据实体类型</typeparam>
    /// <typeparam name="TEntityInfoInputDto">数据实体输入DTO类型</typeparam>
    /// <typeparam name="TEntityRole">实体角色类型</typeparam>
    /// <typeparam name="TEntityRoleInputDto">实体角色输入DTO类型</typeparam>
    /// <typeparam name="TRoleKey">角色编号类型</typeparam>
    /// <typeparam name="TEntityUser">实体用户类型</typeparam>
    /// <typeparam name="TEntityUserInputDto">实体用户输入DTO类型</typeparam>
    /// <typeparam name="TUserKey">用户编号类型</typeparam>
    [Description("数据权限模块")]
    [DependsOnPacks(typeof(EventBusPack), typeof(EntityInfoPack))]
    public abstract class DataAuthorizationPackBase<TDataAuthorizationManager, TDataAuthCache, TEntityInfo, TEntityInfoInputDto,
        TEntityRole, TEntityRoleInputDto, TRoleKey, TEntityUser, TEntityUserInputDto, TUserKey> : PackBase
        where TDataAuthorizationManager : class, IEntityInfoStore<TEntityInfo, TEntityInfoInputDto>, IEntityRoleStore<TEntityRole, TEntityRoleInputDto, TRoleKey>, IEntityUserStore<TEntityUser, TEntityUserInputDto, TUserKey>
        where TDataAuthCache : IDataAuthCache
        where TEntityInfo : IEntityInfo
        where TEntityInfoInputDto : EntityInfoInputDtoBase
        where TEntityRole : EntityRoleBase<TRoleKey>
        where TEntityRoleInputDto : EntityRoleInputDtoBase<TRoleKey>
        where TEntityUser : EntityUserBase<TUserKey>
        where TEntityUserInputDto : EntityUserInputDtoBase<TUserKey>
    {
        #region "属性"
        #region "获取 模块级别"
        /// <summary>
        /// 获取 模块级别
        /// <para>级别越小越先启动</para>
        /// </summary>
        public override PackLevel Level => PackLevel.Application;
        #endregion
        #region "获取 模块启动顺序编号"
        /// <summary>
        /// 获取 模块启动顺序编号
        /// <para>模块启动的顺序先按级别启动，级别内部再按此顺序启动，级别默认为0，表示无依赖，需要在同级别有依赖顺序的时候，再重写为 >0 的顺序值。</para>
        /// </summary>
        public override int OrderNo => 4;
        #endregion

        #endregion

        #region "方法"
        #region "将模块服务添加到依赖注入服务容器中"
        /// <summary>
        /// 将模块服务添加到依赖注入服务容器中
        /// </summary>
        /// <param name="services">依赖注入服务容器</param>
        /// <returns></returns>
        public override IServiceCollection AddServices(IServiceCollection services)
        {
            services.AddSingleton(typeof(IDataAuthCache), typeof(TDataAuthCache));

            services.AddScoped<IDataAuthService, DataAuthService>();
            services.AddScoped<TDataAuthorizationManager>();
            services.AddScoped(typeof(IEntityInfoStore<TEntityInfo, TEntityInfoInputDto>), provider => provider.GetService<TDataAuthorizationManager>());
            services.AddScoped(typeof(IEntityRoleStore<TEntityRole, TEntityRoleInputDto, TRoleKey>), provider => provider.GetService<TDataAuthorizationManager>());
            services.AddScoped(typeof(IEntityUserStore<TEntityUser, TEntityUserInputDto, TUserKey>), provider => provider.GetService<TDataAuthorizationManager>());

            services.AddEventHandler<DataAuthCacheRefreshEventHandler>();
            services.AddEventHandler<DataCacheRefreshEventHandler>();

            return services;
        }
        #endregion
        #region "应用模块服务"
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            IEntityInfoHandler entityInfoHandler = provider.GetService<IEntityInfoHandler>();
            entityInfoHandler.RefreshCache();

            IDataAuthCache dataAuthCache = provider.GetService<IDataAuthCache>();
            dataAuthCache.BuildCaches();

            IsEnabled = true;
        }
        #endregion

        #endregion

    }
    #endregion

}
